﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Drawing;

namespace LexLib.LexemNameSpace
{
    /// <summary>
    /// Общий интерфейс для всех типов
    /// </summary>
    public interface ILexemType
    {
        bool RequireBlank//некоторые типы лексем не требуют пробела после себя
        {
            get;
        }

        string GetColor//цвет, соответствующий типу лексемы
        {
            get;
        }
    }

    /// <summary>
    /// отвечает за ключевое слово Program (смотри bnf)
    /// </summary>
    [Serializable]
    public class ProgramType : ILexemType
    { 
        #region ILexemType Members

        public string GetColor
        {
            get { return "{\\cf2\\cb1 "; }
        }

        public bool RequireBlank
        {
            get { return true; }
        }
        #endregion
    }
    /// <summary>
    /// Тип для имен переменных (т.е. всего того, что не подошло под другие типы)
    /// Работает
    /// </summary>
    public class VarNameType : ILexemType
    {
        private string text;
        /// <summary>
        /// Конструктор, принимающий в себя слово - имя переменной
        /// </summary>
        /// <param name="tmp"></param>
        public VarNameType(string tmp)
        {
            this.text = tmp;
        }

        public string GetWord
        {
            get
            {
                return this.text;
            }
            set
            {
                this.text = value; 
            }
        }
       
        #region ILexemType Members

        public bool RequireBlank
        {
            get { return true; }
        }

        public string GetColor
        {
            get { return "{\\cf1\\cb1 "; }
        }

        #endregion
    }
    /// <summary>
    /// Тип для ключевых слов определяющих типы
    /// </summary>
    [Serializable]
    public class TypeDefinition:ILexemType
    {
        #region ILexemType Members
        public string GetColor
        {
            get { return "{\\cf2\\cb1 "; }
        }

        public bool RequireBlank
        {
            get { return true; }
        }
        #endregion
    }
    /// <summary>
    /// Тип всевозможных констант языка
    /// </summary>
    [Serializable]
    public abstract class ConstType : ILexemType
    {
        #region ILexemType Members

        public bool RequireBlank
        {
            get { return true; }
        }

        public abstract string GetColor
        {
            get;
        }

        #endregion
    }
    /// <summary>
    /// Тип для определения определения целых чисел
    /// Работает
    /// </summary>
    [Serializable]
    public class IntType : TypeDefinition
    {
    }
    /// <summary>
    /// Тип целого числа
    /// </summary>
    public class IntNumberType : ConstType
    {
        override public string GetColor
        {
            get { return "{\\cf1\\cb1 "; }
        }
    }
    /// <summary>
    /// Тип для определения числа с плавающей точкой
    /// Работает
    /// </summary>
    [Serializable]
    public class DoubleType : TypeDefinition
    {
    }
    /// <summary>
    /// Тип числа с плавающей точкой
    /// </summary>
    public class DoubleNumberType : ConstType
    {
        override public string GetColor
        {
            get { return "{\\cf1\\cb1 "; }
        }
    }
    /// <summary>
    /// Тип для определения опеделения строки
    /// </summary>
    [Serializable]
    public class StringType : TypeDefinition
    {
    }
    /// <summary>
    /// Тип строки
    /// Работает
    /// </summary>
    public class ConstString : ConstType
    {
        override public string GetColor
        {
            get { return "{\\cf4\\cb1 "; }
        }
    }
    /// <summary>
    /// Тип для определения символа
    /// </summary>
    [Serializable]
    public class CharType : TypeDefinition
    {
    }
    /// <summary>
    /// Тип для символа
    /// Работает
    /// </summary>
    public class ConstChar : ConstType
    {
        override public string GetColor
        {
            get { return "{\\cf1\\cb1 "; }
        }
    }
    /// <summary>
    /// Тип для определения определения булевских переменных 
    /// </summary>
    [Serializable]
    public class BoolType : TypeDefinition
    {
    }
    /// <summary>
    /// Тип для булевских переменных тип для true false
    /// Работает
    /// </summary>
    [Serializable]
    public class ConstBool : ConstType
    {
        override public string GetColor
        {
            get { return "{\\cf2\\cb1 "; }
        }
    }
    /// <summary>
    /// Тип ключевых слов, добавленных для подсветки, но не присутствующих в оригинальном C
    /// Работает
    /// </summary>
    [Serializable]
    public class OtherKeyWord : ConstType
    {
        //public OtherKeyWord()
        //{
        //    typeOfKeyWord = true;
        //    cl = "{\\cf2\\cb1 ";
        //}
        public OtherKeyWord(bool isVar, string col)
        {
            typeOfKeyWord = isVar;
            cl = col;
            colored = true;
        }
        private string cl;
        private bool typeOfKeyWord;//Как распознается парсером - как имя переменной (true) или как новое ключевое слово (false) 
        private bool colored;
        override public string GetColor
        {
            get {
                if (colored)
                {
                    return cl;
                }
                else
                {
                    return "{\\cf1\\cb1 ";
                }
                }
        }
        
        public bool Colored
        {
            get { return colored; }
            set { colored = value; }
        }
        public bool IsVariable
        {
            get { return typeOfKeyWord; }
            //set { typeOfKeyWord = value; }
        }

    }      
    /// <summary>
    /// Тип скобки
    /// Работает
    /// </summary>
    [Serializable]
    public class Bracket : ILexemType
    {   
        #region ILexemType Members

        public bool RequireBlank
        {
            get { return false; }
        }

        public string GetColor
        {
            get { return "{\\cf1\\cb1 "; }
        }

        #endregion
    }
    /// <summary>
    /// Тип открывающей обычной скобки
    /// Работает
    /// </summary>
    [Serializable]
    public class OpenNormalBracketType : Bracket
    {
    }
    /// <summary>
    /// Тип закрывающей обычной скобки
    /// Работает
    /// </summary>
    [Serializable]
    public class CloseNormalBracketType : Bracket
    {
    }   
    /// <summary>
    /// Тип открывающей фигуной скобки
    /// Работает
    /// </summary>
    [Serializable]
    public class OpenFigureBracketType : Bracket
    {
    }
    /// <summary>
    /// Тип закрывающей фигурной скобки
    /// Работает
    /// </summary>
    [Serializable]
    public class CloseFigureBracketType : Bracket
    {
    }        
    /// <summary>
    /// Тип ";"
    /// Работает
    /// </summary>
    [Serializable]
    public class EndOfLineType:ILexemType
    {
        #region ILexemType Members

        public bool RequireBlank
        {
            get { return false; }
        }

        public string GetColor
        {
            get { return "{\\cf1\\cb1 "; }
        }

        #endregion
    }
    /// <summary>
    /// Тип цикла for
    /// Работает
    /// </summary>
    [Serializable]
    public class For:ILexemType
    {
        #region ILexemType Members

        public string GetColor
        {
            get { return "{\\cf2\\cb1 "; }
        }

        public bool RequireBlank
        {
            get { return true; }
        }
        #endregion
    }
    /// <summary>
    /// Тип цикла while
    /// Работает
    /// </summary>
    [Serializable]
    public class While : ILexemType
    {
        #region ILexemType Members

        public bool RequireBlank
        {
            get { return true; }
        }

        public string GetColor
        {
            get { return "{\\cf2\\cb1 "; }
        }

        #endregion
    }
    /// <summary>
    /// Тип условного оператора if
    /// Работает
    /// </summary>
    [Serializable]
    public class If:ILexemType
    {
        #region ILexemType Members

        public string GetColor
        {
            get { return "{\\cf2\\cb1 "; }
        }

        public bool RequireBlank
        {
            get { return true; }
        }
        #endregion
    }
    /// <summary>
    /// Тип else
    /// Работает
    /// </summary>
    [Serializable]
    public class Else : ILexemType
    {
        #region ILexemType Members

        public bool RequireBlank
        {
            get { return true; }
        }

        public string GetColor
        {
            get { return "{\\cf2\\cb1 "; }
        }

        #endregion
    }
    /// <summary>
    /// Тип объявления функции
    /// Работает
    /// </summary>
    [Serializable]
    public class Function:ILexemType
    {
        #region ILexemType Members

        public bool RequireBlank
        {
            get { return true; }
        }

        public string GetColor
        {
            get { return "{\\cf2\\cb1 "; }
        }

        #endregion
    }
    /// <summary>
    /// Тип возвратителя (хз как ещё сказать)
    /// Работает
    /// </summary>
    [Serializable]
    public class Return : ILexemType
    {
        #region ILexemType Members

        public bool RequireBlank
        {
            get { return true; }
        }

        public string GetColor
        {
            get { return "{\\cf2\\cb1 "; }
        }

        #endregion
    }
    /// <summary>
    /// Тип комментария
    /// Работает
    /// </summary>
    public class Comment : ILexemType
    {
        #region ILexemType Members

        public string GetColor
        {
            get { return "{\\cf3\\cb1 "; }
        }

        public bool RequireBlank
        {
            get { return true; }//вроде на самом деле не требует - но по структуре лексера, нам не важно требует или нет
        }

        #endregion
    }
    /// <summary>
    /// Тип операторов +,-,*,/
    /// Работает
    /// </summary>
    [Serializable]
    public class SyntaxType:ILexemType
    {
        #region ILexemType Members

        public string GetColor
        {
            get { return "{\\cf1\\cb1 "; }
        }

        public bool RequireBlank
        {
            get { return false; }
        }

        #endregion
    }
    
    /// <summary>
    /// Тип ++ += -= *= /=
    /// Работает
    /// </summary>
    [Serializable]
    public class Modificator : ILexemType
    {
        #region ILexemType Members

        public string GetColor
        {
            get { return "{\\cf1\\cb1 "; }
        }

        public bool RequireBlank
        {
            get { return false; }
        }

        #endregion
    }

    /// <summary>
    /// Тип ошибки
    /// Работает
    /// </summary>
    public class Error : ILexemType
    {
        #region ILexemType Members

        public bool RequireBlank
        {
            get { return false; }
        }

        public string GetColor
        {
            get { return "{\\cf6\\cb1 "; }
        }

        #endregion
    }
    /// <summary>
    /// Тип условия
    /// Работает
    /// </summary>
    [Serializable]
    public class ConditionType : ILexemType
    {
        #region ILexemType Members

        public bool RequireBlank
        {
            get { return false; }
        }

        public string GetColor
        {
            get { return "{\\cf1\\cb1 "; }
        }

        #endregion
    }

    /// <summary>
    /// Коля, не три этот класс, он мне нужен в парсере.
    /// Никак его не описывай, в лексере не будут хранится лексемы с таким типом
    /// Мне он нужен только для того, чтобы было удобно создавать узлы синтаксического дерева типа
    /// список детей:"("+expression+")"
    /// </summary>
    [Serializable]
    public class InterNormalBraketsType : ILexemType
    {
        #region ILexemType Members

        public bool RequireBlank
        {
            get { return false; }
        }

        public string GetColor
        {
            get { return "{\\cf1\\cb1 "; }
        }

        #endregion
    }
    
    /// <summary>
    /// && ||
    /// </summary>
    [Serializable]
    public class LogicalType : ILexemType
    {
        #region ILexemType Members

        public string GetColor
        {
            get { return "{\\cf1\\cb1 "; }
        }

        public bool RequireBlank
        {
            get { return true; }
        }
        #endregion
    }
}
